package com.mycat.chat.one;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * 聊天服务发布者
 *
 * @author roger.
 * @email 190642964@qq.com
 * @create 2017-02-13
 */
public class ChatServerExporter {

    // 线程池大小为：可用处理器的Java虚拟机的数量
    static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    static List<ChatServerExporterClient> clients = new ArrayList<>();

    public static void exporter(String hostname, int port) throws Exception {
        ServerSocket server = new ServerSocket();
        try {
            server.bind(new InetSocketAddress(hostname, port));
            ChatServerExporterClient client = null;
            while (true) {
                client = new ChatServerExporterClient(server.accept());
                // 监听客户端的TCP连接
                executor.execute(client);
                clients.add(client);
            }
        } catch (BindException e) {
            System.out.println("当前端口" + port + "正在使用.....");
        } finally {
            server.close();
        }
    }

    /**
     * 聊天服务处理线程
     */
    private static class ChatServerExporterClient implements Runnable {

        private Socket client = null;
        private ObjectInputStream input = null;
        private ObjectOutputStream output = null;

        public ChatServerExporterClient(Socket client) {
            try {
                this.client = client;
                input = new ObjectInputStream(this.client.getInputStream());
                output = new ObjectOutputStream(this.client.getOutputStream());
                System.out.println("a client connected!!!ServerName : " + Thread.currentThread().getId());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * 向客户端发送消息
         *
         * @param message 消息体
         */
        public void sendMessage(String message) {
            try {
                output.writeUTF(message);
                output.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            try {
                while (true) {
                    String message = input.readUTF();
                    System.out.println("服务端收到消息：" + message);

                    for (int i = 0; i < clients.size(); i++) {
                        ChatServerExporterClient sendClient = clients.get(i);
                        if (this.client != sendClient.getClient()) {
                            sendClient.sendMessage(message);
                        }
                    }
                }
            } catch (EOFException e) {
                System.out.println("a client close!!!");
                clients.remove(this);
                System.out.println("当前在线客户端" + clients.size());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != output) {
                        output.close();
                    }
                    if (null != input) {
                        input.close();
                    }
                    if (null != client) {
                        client.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public Socket getClient() {
            return client;
        }

        public void setClient(Socket client) {
            this.client = client;
        }
    }

}
